package com.cuijian.demo.service;

import com.cuijian.demo.config.RocketMQConfig;
import com.cuijian.demo.mq.MQConstants;
import com.cuijian.demo.model.LogisticsOrder;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import com.alibaba.fastjson2.JSON;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class RocketMQProducerService {

    private DefaultMQProducer producer;

    public RocketMQProducerService() {
        // 只有在MQ启用时才初始化生产者
        if (RocketMQConfig.getInstance().isMqEnabled()) {
            this.producer = RocketMQConfig.getInstance().getProducer();
        }
    }

    /**
     * 发送订单创建消息 - 优化版本
     */
    public SendResult sendOrderCreatedMessage(LogisticsOrder order) {
        if (order == null) {
            System.err.println("订单数据为空，无法发送消息");
            return null;
        }

        try {
            // 构建订单创建消息
            OrderCreatedMessage message = new OrderCreatedMessage();
            message.setOrderId(order.getId());
            message.setUserId(order.getUserId());
            message.setTrackingNumber(order.getTrackingNumber());
            message.setRecipientName(order.getRecipientName());
            message.setRecipientAddress(order.getRecipientAddress());
            message.setRecipientPhone(order.getRecipientPhone());
            message.setLogisticsCompany(order.getLogisticsCompany());
            message.setStatus(order.getStatus());
            message.setRemarks(order.getRemarks());
            message.setOrderTime(order.getOrderTime());
            message.setCreateTime(System.currentTimeMillis());

            // 发送消息
            SendResult result = sendMessage(
                    MQConstants.TOPIC_ORDER,
                    MQConstants.TAG_ORDER_CREATED,
                    "ORDER_CREATED_" + order.getTrackingNumber(),
                    message
            );

            System.out.printf("✅ 订单创建消息发送成功: 订单ID=%d, 物流单号=%s, MsgId=%s%n",
                    order.getId(), order.getTrackingNumber(), result.getMsgId());
            return result;

        } catch (Exception e) {
            System.err.printf("❌ 订单创建消息发送失败: 订单ID=%d, 物流单号=%s, 错误=%s%n",
                    order.getId(), order.getTrackingNumber(), e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 发送订单创建消息 - 简化版本
     */
    public boolean sendSimpleOrderCreatedMessage(Long orderId, String trackingNumber, String recipientName, String logisticsCompany) {
        if (!RocketMQConfig.getInstance().isMqEnabled()) {
            System.out.println("⚠️ MQ未启用，跳过发送订单创建消息");
            return false;
        }

        try {
            Map<String, Object> message = new HashMap<>();
            message.put("orderId", orderId);
            message.put("trackingNumber", trackingNumber);
            message.put("recipientName", recipientName);
            message.put("logisticsCompany", logisticsCompany);
            message.put("eventType", "ORDER_CREATED");
            message.put("timestamp", System.currentTimeMillis());

            SendResult result = sendMessage(
                    MQConstants.TOPIC_ORDER,
                    MQConstants.TAG_ORDER_CREATED,
                    "ORDER_CREATED_" + trackingNumber,
                    message
            );

            System.out.printf("✅ 简化版订单创建消息发送成功: 订单ID=%d, 物流单号=%s%n", orderId, trackingNumber);
            return true;

        } catch (Exception e) {
            System.err.printf("❌ 简化版订单创建消息发送失败: 订单ID=%d, 错误=%s%n", orderId, e.getMessage());
            return false;
        }
    }

    /**
     * 发送订单状态变更消息 - 优化版本
     */
    public SendResult sendOrderStatusChangedMessage(Long orderId, String trackingNumber,
                                                    Integer oldStatus, Integer newStatus) {
        if (!RocketMQConfig.getInstance().isMqEnabled()) {
            System.out.println("⚠️ MQ未启用，跳过发送状态变更消息");
            return null;
        }

        try {
            OrderStatusChangeMessage message = new OrderStatusChangeMessage();
            message.setOrderId(orderId);
            message.setTrackingNumber(trackingNumber);
            message.setOldStatus(oldStatus);
            message.setNewStatus(newStatus);
            message.setChangeTime(System.currentTimeMillis());
            message.setStatusText(getStatusText(newStatus));

            SendResult result = sendMessage(
                    MQConstants.TOPIC_ORDER,
                    MQConstants.TAG_ORDER_STATUS_CHANGED,
                    "STATUS_CHANGE_" + trackingNumber,
                    message
            );

            System.out.printf("✅ 订单状态变更消息发送成功: 订单ID=%d, 状态 %d→%d%n",
                    orderId, oldStatus, newStatus);
            return result;

        } catch (Exception e) {
            System.err.printf("❌ 订单状态变更消息发送失败: 订单ID=%d, 错误=%s%n", orderId, e.getMessage());
            return null;
        }
    }

    /**
     * 发送订单已签收消息 - 优化版本
     */
    public SendResult sendOrderDeliveredMessage(Long orderId, String trackingNumber) {
        if (!RocketMQConfig.getInstance().isMqEnabled()) {
            System.out.println("⚠️ MQ未启用，跳过发送签收消息");
            return null;
        }

        try {
            OrderDeliveredMessage message = new OrderDeliveredMessage();
            message.setOrderId(orderId);
            message.setTrackingNumber(trackingNumber);
            message.setDeliveredTime(System.currentTimeMillis());

            SendResult result = sendMessage(
                    MQConstants.TOPIC_ORDER,
                    MQConstants.TAG_ORDER_DELIVERED,
                    "ORDER_DELIVERED_" + trackingNumber,
                    message
            );

            System.out.printf("✅ 订单签收消息发送成功: 订单ID=%d, 物流单号=%s%n", orderId, trackingNumber);
            return result;

        } catch (Exception e) {
            System.err.printf("❌ 订单签收消息发送失败: 订单ID=%d, 错误=%s%n", orderId, e.getMessage());
            return null;
        }
    }

    /**
     * 发送用户注册消息 - 优化版本
     */
    public SendResult sendUserRegisterMessage(Long userId, String username, String email) {
        if (!RocketMQConfig.getInstance().isMqEnabled()) {
            System.out.println("⚠️ MQ未启用，跳过发送用户注册消息");
            return null;
        }

        try {
            UserRegisterMessage message = new UserRegisterMessage();
            message.setUserId(userId);
            message.setUsername(username);
            message.setEmail(email);
            message.setRegisterTime(System.currentTimeMillis());

            SendResult result = sendMessage(
                    MQConstants.TOPIC_USER,
                    MQConstants.TAG_USER_REGISTER,
                    "USER_REGISTER_" + username,
                    message
            );

            System.out.printf("✅ 用户注册消息发送成功: 用户ID=%d, 用户名=%s%n", userId, username);
            return result;

        } catch (Exception e) {
            System.err.printf("❌ 用户注册消息发送失败: 用户ID=%d, 错误=%s%n", userId, e.getMessage());
            return null;
        }
    }

    /**
     * 发送通知消息 - 优化版本
     */
    public SendResult sendNotificationMessage(String to, String title, String content, String type) {
        if (!RocketMQConfig.getInstance().isMqEnabled()) {
            System.out.println("⚠️ MQ未启用，跳过发送通知消息");
            return null;
        }

        try {
            NotificationMessage message = new NotificationMessage();
            message.setTo(to);
            message.setTitle(title);
            message.setContent(content);
            message.setType(type);
            message.setSendTime(System.currentTimeMillis());

            String tag = MQConstants.TAG_SYSTEM;
            if ("sms".equalsIgnoreCase(type)) {
                tag = MQConstants.TAG_SMS;
            } else if ("email".equalsIgnoreCase(type)) {
                tag = MQConstants.TAG_EMAIL;
            }

            SendResult result = sendMessage(
                    MQConstants.TOPIC_NOTIFICATION,
                    tag,
                    "NOTIFICATION_" + System.currentTimeMillis(),
                    message
            );

            System.out.printf("✅ 通知消息发送成功: 类型=%s, 接收方=%s%n", type, to);
            return result;

        } catch (Exception e) {
            System.err.printf("❌ 通知消息发送失败: 类型=%s, 错误=%s%n", type, e.getMessage());
            return null;
        }
    }

    /**
     * 通用发送消息方法 - 优化版本
     */
    public SendResult sendMessage(String topic, String tags, String keys, Object data) {
        if (!RocketMQConfig.getInstance().isMqEnabled()) {
            System.out.println("⚠️ MQ未启用，跳过发送消息");
            return null;
        }

        if (producer == null) {
            System.err.println("❌ RocketMQ生产者未初始化");
            return null;
        }

        try {
            String messageBody = JSON.toJSONString(data);
            Message msg = new Message(topic, tags, keys, messageBody.getBytes(StandardCharsets.UTF_8));

            SendResult sendResult = producer.send(msg);
            System.out.printf("✅ 消息发送成功: Topic=%s, Tags=%s, Keys=%s, MsgId=%s%n",
                    topic, tags, keys, sendResult.getMsgId());
            return sendResult;

        } catch (Exception e) {
            System.err.printf("❌ 消息发送失败: Topic=%s, Tags=%s, 错误=%s%n", topic, tags, e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("发送消息失败", e);
        }
    }

    /**
     * 发送异步消息 - 优化版本
     */
    public void sendAsyncMessage(String topic, String tags, String keys, Object data,
                                 Runnable successCallback, Runnable errorCallback) {
        if (!RocketMQConfig.getInstance().isMqEnabled()) {
            System.out.println("⚠️ MQ未启用，跳过发送异步消息");
            if (successCallback != null) {
                successCallback.run();
            }
            return;
        }

        if (producer == null) {
            System.err.println("❌ RocketMQ生产者未初始化");
            if (errorCallback != null) {
                errorCallback.run();
            }
            return;
        }

        try {
            String messageBody = JSON.toJSONString(data);
            Message msg = new Message(topic, tags, keys, messageBody.getBytes(StandardCharsets.UTF_8));

            producer.send(msg, new org.apache.rocketmq.client.producer.SendCallback() {
                @Override
                public void onSuccess(SendResult sendResult) {
                    System.out.printf("✅ 异步消息发送成功: Topic=%s, Tags=%s, MsgId=%s%n",
                            topic, tags, sendResult.getMsgId());
                    if (successCallback != null) {
                        successCallback.run();
                    }
                }

                @Override
                public void onException(Throwable e) {
                    System.err.printf("❌ 异步消息发送失败: Topic=%s, Tags=%s, 错误=%s%n",
                            topic, tags, e.getMessage());
                    if (errorCallback != null) {
                        errorCallback.run();
                    }
                }
            });

        } catch (Exception e) {
            System.err.printf("❌ 发送异步消息失败: Topic=%s, Tags=%s, 错误=%s%n", topic, tags, e.getMessage());
            if (errorCallback != null) {
                errorCallback.run();
            }
        }
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(Integer status) {
        if (status == null) return "未知";

        switch (status) {
            case LogisticsOrder.STATUS_PENDING: return "待发货";
            case LogisticsOrder.STATUS_SHIPPING: return "运输中";
            case LogisticsOrder.STATUS_DELIVERING: return "派送中";
            case LogisticsOrder.STATUS_DELIVERED: return "已签收";
            case LogisticsOrder.STATUS_EXCEPTION: return "异常";
            default: return "未知";
        }
    }

    /**
     * 检查MQ是否可用
     */
    public boolean isMqEnabled() {
        return RocketMQConfig.getInstance().isMqEnabled();
    }

    // 消息实体类
    public static class OrderCreatedMessage {
        private Long orderId;
        private Long userId;
        private String trackingNumber;
        private String recipientName;
        private String recipientAddress;
        private String recipientPhone;
        private String logisticsCompany;
        private Integer status;
        private String remarks;
        private java.util.Date orderTime;
        private Long createTime;

        // getter and setter
        public Long getOrderId() { return orderId; }
        public void setOrderId(Long orderId) { this.orderId = orderId; }

        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }

        public String getTrackingNumber() { return trackingNumber; }
        public void setTrackingNumber(String trackingNumber) { this.trackingNumber = trackingNumber; }

        public String getRecipientName() { return recipientName; }
        public void setRecipientName(String recipientName) { this.recipientName = recipientName; }

        public String getRecipientAddress() { return recipientAddress; }
        public void setRecipientAddress(String recipientAddress) { this.recipientAddress = recipientAddress; }

        public String getRecipientPhone() { return recipientPhone; }
        public void setRecipientPhone(String recipientPhone) { this.recipientPhone = recipientPhone; }

        public String getLogisticsCompany() { return logisticsCompany; }
        public void setLogisticsCompany(String logisticsCompany) { this.logisticsCompany = logisticsCompany; }

        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }

        public String getRemarks() { return remarks; }
        public void setRemarks(String remarks) { this.remarks = remarks; }

        public java.util.Date getOrderTime() { return orderTime; }
        public void setOrderTime(java.util.Date orderTime) { this.orderTime = orderTime; }

        public Long getCreateTime() { return createTime; }
        public void setCreateTime(Long createTime) { this.createTime = createTime; }
    }

    public static class OrderStatusChangeMessage {
        private Long orderId;
        private String trackingNumber;
        private Integer oldStatus;
        private Integer newStatus;
        private String statusText;
        private Long changeTime;

        // getter and setter
        public Long getOrderId() { return orderId; }
        public void setOrderId(Long orderId) { this.orderId = orderId; }

        public String getTrackingNumber() { return trackingNumber; }
        public void setTrackingNumber(String trackingNumber) { this.trackingNumber = trackingNumber; }

        public Integer getOldStatus() { return oldStatus; }
        public void setOldStatus(Integer oldStatus) { this.oldStatus = oldStatus; }

        public Integer getNewStatus() { return newStatus; }
        public void setNewStatus(Integer newStatus) { this.newStatus = newStatus; }

        public String getStatusText() { return statusText; }
        public void setStatusText(String statusText) { this.statusText = statusText; }

        public Long getChangeTime() { return changeTime; }
        public void setChangeTime(Long changeTime) { this.changeTime = changeTime; }
    }

    public static class OrderDeliveredMessage {
        private Long orderId;
        private String trackingNumber;
        private Long deliveredTime;

        // getter and setter
        public Long getOrderId() { return orderId; }
        public void setOrderId(Long orderId) { this.orderId = orderId; }

        public String getTrackingNumber() { return trackingNumber; }
        public void setTrackingNumber(String trackingNumber) { this.trackingNumber = trackingNumber; }

        public Long getDeliveredTime() { return deliveredTime; }
        public void setDeliveredTime(Long deliveredTime) { this.deliveredTime = deliveredTime; }
    }

    public static class UserRegisterMessage {
        private Long userId;
        private String username;
        private String email;
        private Long registerTime;

        // getter and setter
        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }

        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }

        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }

        public Long getRegisterTime() { return registerTime; }
        public void setRegisterTime(Long registerTime) { this.registerTime = registerTime; }
    }

    public static class NotificationMessage {
        private String to;
        private String title;
        private String content;
        private String type;
        private Long sendTime;

        // getter and setter
        public String getTo() { return to; }
        public void setTo(String to) { this.to = to; }

        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }

        public String getContent() { return content; }
        public void setContent(String content) { this.content = content; }

        public String getType() { return type; }
        public void setType(String type) { this.type = type; }

        public Long getSendTime() { return sendTime; }
        public void setSendTime(Long sendTime) { this.sendTime = sendTime; }
    }
}